package org.dromara.tearoom.dubbo;


import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.tearoom.api.RemoteAppUserService;
import org.dromara.tearoom.api.domain.vo.RemoteAppUserVo;
import org.dromara.tearoom.api.model.XcxLoginAppUser;
import org.dromara.tearoom.domain.TerUser;
import org.dromara.tearoom.domain.bo.TerAccountsBo;
import org.dromara.tearoom.domain.bo.TerUserBo;
import org.dromara.tearoom.domain.enums.IotDeviceClassEnum;
import org.dromara.tearoom.domain.vo.TerUserVo;
import org.dromara.tearoom.domain.vo.WxPayProperties;
import org.dromara.tearoom.mapper.TerUserMapper;
import org.dromara.tearoom.service.ITerAccountsService;
import org.dromara.tearoom.service.ITerIotDeviceService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 用户服务
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
@DubboService
@EnableConfigurationProperties(WxPayProperties.class)
public class RemoteAppUserServiceImpl implements RemoteAppUserService {
    private final TerUserMapper terUserMapper;
    private final WxPayProperties wxPayProperties;
    private final WxMaService wxMaService;
    private final ITerIotDeviceService iotDeviceService;
    private final ITerAccountsService terAccountsService;
    private LambdaQueryWrapper<TerUser> buildQueryWrapper(TerUserBo bo) {
        LambdaQueryWrapper<TerUser> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TerUser::getId);
        lqw.eq(TerUser::getOpenId, bo.getOpenId());
        return lqw;
    }



    /**
     * 通过openid查询用户信息
     *
     * @param openid openid
     * @param mobileCode mobileCode
     * @return 结果
     */
    @Override
    public XcxLoginAppUser getUserInfoByOpenidAndMobile(String openid,String mobileCode) throws UserException {
        XcxLoginAppUser loginUser = new XcxLoginAppUser();
        loginUser.setOpenId(openid);
        TerUserBo bo = new TerUserBo();
        bo.setOpenId(openid);
        LambdaQueryWrapper<TerUser> lqw = buildQueryWrapper(bo);
        TerUser terUser= terUserMapper.selectOne(lqw);
        Date loginTime = new Date();
        // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
        // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
        if (ObjectUtil.isNull(terUser)) {
            //新增用户信息
            TerUser add = MapstructUtils.convert(bo, TerUser.class);
            add.setNickname(RandomUtil.randomString(6));
            add.setLastLoginAt(loginTime);
            add.setMobile(this.getMobileByCode(mobileCode));
            add.setCreateTime(new Date());
            terUserMapper.insert(add);
            loginUser.setId(add.getId());
            loginUser.setNickname(add.getNickname());
            loginUser.setLastLoginAt(loginTime);
            loginUser.setMobile(add.getMobile());
            TerAccountsBo bo2 = new TerAccountsBo();
            bo2.setCreateDept(1L);
            bo2.setCreateBy(1L);
            bo2.setCreateTime(loginTime);
            bo2.setMemberId(add.getId());
            terAccountsService.insertByBo(bo2);
        }else{
            loginUser.setId(terUser.getId());
            loginUser.setNickname(terUser.getNickname());
            loginUser.setLastLoginAt(loginTime);
            if(StrUtil.isBlank(terUser.getMobile())){
                terUser.setMobile(this.getMobileByCode(mobileCode));
            }
            loginUser.setMobile(terUser.getMobile());
            terUser.setLastLoginAt(loginTime);
            terUserMapper.updateById(terUser);
        }
        return loginUser;
    }

    private String getMobileByCode(String mobileCode) {
        if(StrUtil.isNotBlank(mobileCode)){
            try {
                WxMaPhoneNumberInfo wxMaPhoneNumberInfo=wxMaService.getUserService().getNewPhoneNoInfo(mobileCode);
                if(ObjectUtil.isNotEmpty(wxMaPhoneNumberInfo)){
                    return wxMaPhoneNumberInfo.getPhoneNumber();
                }
            } catch (WxErrorException e) {
                throw new ServiceException(e.getError().getErrorMsg());
            }
        }
        return null;
    }


    /**
     * 通过appId查询密钥
     *
     * @param appId AppId
     * @return 结果
     */
    @Override
    public String selectAppSecret(String appId) {
        return wxPayProperties.getAppsecret();
    }

    /**
     * 通过userId查询用户账户
     *
     * @param userId 用户id
     * @return 结果
     */
    @Override
    public String selectUserNameById(Long userId) {
        TerUserVo terUserVo=terUserMapper.selectVoById(userId);
        if(ObjectUtil.isNotEmpty(terUserVo)){
            return terUserVo.getNickname();
        }
        return "";
    }

    /**
     * 通过用户ID查询用户账户
     *
     * @param userIds 用户ID 多个用逗号隔开
     * @return 用户名称
     */
    @Override
    public String selectNicknameByIds(String userIds) {
        return "";
    }

    /**
     * 通过用户ID查询用户手机号
     *
     * @param userId 用户id
     * @return 用户手机号
     */
    @Override
    public String selectPhoneById(Long userId) {
        TerUserVo terUserVo=terUserMapper.selectVoById(userId);
        if(ObjectUtil.isNotEmpty(terUserVo)){
            return terUserVo.getMobile();
        }
        return "";
    }

    /**
     * 更新用户信息
     *
     * @param userId 用户ID
     * @param ip     IP地址
     */
    @Override
    public void recordLoginInfo(Long userId, String ip) {

    }

    /**
     * 通过用户ID查询用户列表
     *
     * @param userIds 用户ids
     * @return 用户列表
     */
    @Override
    public List<RemoteAppUserVo> selectListByIds(List<Long> userIds) {
        return List.of();
    }

    /**
     * 控制断路器开关
     *
     * @param roomId
     * @param onOff
     */
    @Override
    public void operateChopper(Long roomId, Boolean onOff) {
        iotDeviceService.operateDeviceOnOffByClass(roomId,onOff, IotDeviceClassEnum.CHOPPER.getType());
    }


}
